using System.Collections.Generic;
using System.Windows;

using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.UnityExtensions;
using Microsoft.Practices.Unity;

using Matchingo.Common.Types.Interfaces;
using Matchingo.Controllers.GameExecutionController;
using Matchingo.Controllers.GameInputController;

// Models
using Matchingo.Models.BackgroundProvider;
using Matchingo.Models.CardControlFactory;
using Matchingo.Models.CardProvider;
using Matchingo.Models.DefaultImageSetResources;
using Matchingo.Models.GameLogicProvider;
using Matchingo.Models.MenuFlowProvider;
using Matchingo.Models.ParticleControlFactory;
using Matchingo.Models.ScoreProvider;
using Matchingo.Models.SettingsProvider;
using Matchingo.Models.VirtualPlayers;
using Matchingo.Models.FacebookScoreProvider;

// View Models
using Matchingo.Modules.AboutScreenModule;
using Matchingo.Modules.BackgroundModule;
using Matchingo.Modules.CardGridModule;
using Matchingo.Modules.FlyoutEffectsModule;
using Matchingo.Modules.HighScoreModule;
using Matchingo.Modules.FacebookHighScoreModule;
using Matchingo.Modules.OptionsModule;
using Matchingo.Modules.ParticleRenderModule;
using Matchingo.Modules.StatusBarModule;
using Matchingo.Modules.TitleScreenModule;
using Matchingo.Modules.FacebookFriendsScoreModule;

// Views
using Matchingo.Modules.AboutScreenModule.Views;
using Matchingo.Modules.BackgroundModule.Views;
using Matchingo.Modules.CardGridModule.Views;
using Matchingo.Modules.FlyoutEffectsModule.Views;
using Matchingo.Modules.HighScoreModule.Views;
using Matchingo.Modules.FacebookHighScoreModule.Views;
using Matchingo.Modules.OptionsModule.Views;
using Matchingo.Modules.ParticleRenderModule.Views;
using Matchingo.Modules.StatusBarModule.Views;
using Matchingo.Modules.TitleScreenModule.Views;
using Matchingo.Modules.FacebookFriendsScoreModule.Views;

namespace Matchingo.Facebook
{
    /// <summary>
    /// The bootstrapper is what takes all the UI Modules and Models, news them up, and straps them all together
    /// </summary>
    public class Bootstrapper : UnityBootstrapper
    {
        private Shell _shell; // what all UI modules will be placed into 

        protected override DependencyObject CreateShell()
        {
            _shell = Container.Resolve<Shell>();
            Application.Current.RootVisual = _shell;
            return _shell;
        }

        protected override void InitializeModules()
        {
            Container.RegisterInstance<IGameUIContainer>(_shell);

            // register our resources ..
            // NOTE:: add addictional card and background set image resources here
            Container.RegisterInstance(new List<IBackgroundSetResources> { new BackgroundSetResources() });
            Container.RegisterInstance(new List<ICardSetResources> { new CardSetResources() });            

            // register our models ..
            Container.RegisterType<IParticleControlFactory, ParticleControlFactory>(new ContainerControlledLifetimeManager());
            Container.RegisterType<ICardUserControlFactory, CardUserControlFactory>(new ContainerControlledLifetimeManager());
            Container.RegisterType<IBackgroundSetProvider, PathBackgroundProvider>(new ContainerControlledLifetimeManager());
            Container.RegisterType<IGameSettingsProvider, GameSettingsProvider>(new ContainerControlledLifetimeManager());
            Container.RegisterType<IGameExecutionFacade, GameExecutionFacade>(new ContainerControlledLifetimeManager());
            Container.RegisterType<IMenuFlowProvider, GameMenuFlowProvider>(new ContainerControlledLifetimeManager());
            Container.RegisterType<IHighScoreProvider, FacebookHighScoreProvider>(new ContainerControlledLifetimeManager());
            Container.RegisterType<ICardSetProvider, PathCardProvider>(new ContainerControlledLifetimeManager());
            Container.RegisterType<IGameInputFacade, GameInputFacade>(new ContainerControlledLifetimeManager());
            Container.RegisterType<IMemoryGameLogic, MemoryGameLogic>(new ContainerControlledLifetimeManager());
            Container.RegisterType<IArtificialPlayer, AIPlayer>(new ContainerControlledLifetimeManager());

            // register our views ..
            Container.RegisterType<IFlyoutEffectsView, FlyoutEffectsView>();
            Container.RegisterType<IParticleEffectsView, ParticleView>();
            Container.RegisterType<ITitleScreenView, TitleScreenView>();
            Container.RegisterType<IAboutScreenView, AboutScreenView>();
            Container.RegisterType<IBackgroundView, BackgroundView>();
            Container.RegisterType<IOptionsScreenView, OptionsView>();
			Container.RegisterType<IFacebookHighScoreScreenView, FacebookHighScoreView>();
			Container.RegisterType<IFacebookFriendsScoreScreenView, FacebookFriendsScoreView>();
			Container.RegisterType<IStatusBarView, StatusBarView>();
            Container.RegisterType<ICardGridView, CardGridView>();

            // .. initialize the models which require some sort of setup ..
            Container.Resolve<IGameSettingsProvider>().Initialize();
            Container.Resolve<IHighScoreProvider>().Initialize();
            Container.Resolve<IMemoryGameLogic>().Initialize();

            // initialize the UI Modules / View Models (this in turn calls GetModuleCatalog()) ..
            base.InitializeModules(); 

            // everything is strapped up and ready to go, start the game engine
            Container.Resolve<IGameExecutionFacade>().StartGameEngineExecution(); 
        }

        protected override IModuleCatalog GetModuleCatalog()
        {
            ModuleCatalog catalog = new ModuleCatalog();
                        
            catalog.AddModule(typeof(ParticleEffectsViewModel));
            catalog.AddModule(typeof(FlyoutEffectsViewModel));
            catalog.AddModule(typeof(OptionsScreenViewModel));
            catalog.AddModule(typeof(TitleScreenViewModel));            
            catalog.AddModule(typeof(AboutScreenViewModel));
            catalog.AddModule(typeof(BackgroundViewModel));
            catalog.AddModule(typeof(StatusBarViewModel));
            catalog.AddModule(typeof(CardGridViewModel));
			catalog.AddModule(typeof(FacebookHighScoreScreenViewModel));
			catalog.AddModule(typeof(FacebookFriendsScoreScreenViewModel));

            return catalog;
        }
    }
}
